package com.zim.access.infrastructurre.protocol.ws;

import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;

import java.net.SocketAddress;

/**
 * websocket 处理器
 *
 * @author hanyue
 * @version 1.0
 * @date 2021/12/22 上午9:28
 */
public class WebsocketHandler extends ChannelDuplexHandler {

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // 如果当前通道关闭了自动读取数据流
        ctx.read();
    }

    /**
     * 请求建立连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) throws Exception {
        /**
         * 1. 查询etcd，询问当前用户元数据
         * 2. 如果当前ip+port 已经存在连接信息，返回连接失败，请勿重复连接多个实例（这种情况理论上应该是不会存在的，但是可以通过修改linux内核建立多个）
         * 3. 如果当前ip+port 不存在连接信息，查询etcd，询问当前各实例机器连接情况，自动选择连接最小（或其它策略）的机器进行连接
         */
        ctx.connect(remoteAddress, localAddress, promise);
    }

    /**
     * 数据开始传输，并转发给下游
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        super.channelRead(ctx, msg);
    }

    @Override
    public void disconnect(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
        ctx.disconnect(promise);
    }

    @Override
    public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
        ctx.close(promise);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.fireExceptionCaught(cause);
    }

    /**
     * 请求断开连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        /**
         * 1. 当前用户断开连接，并下架该用户元数据，在etcd的
         */
        super.channelInactive(ctx);
    }
}
